/* tunnelLib.h - Tunneling Support Library */

/* Copyright 2002 - 2003 Wind River Systems, Inc. */

/*
 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
modification history
--------------------
01k,14jul05,nee  Support for MIPv6
01j,20nov03,niq  Remove copyright_wrs.h file inclusion
01i,20mar03,kal  Code review modifications
01h,30oct02,kal  Added Perform PMTUD option and TUNNEL_CONFIG_PARAMS
01g,04sep02,kal  Fixed tunnelInstInit and tunnelInstDestroy prototypes
01f,15aug02,syy  Merge from version 13 of Accordion Munich branch
01e,11jul02,spm  fixed modification history after automatic merge
01d,11jul02,wrs  automatic merge from version 7 of Accordion Munich branch:
                 (xxjul02,kal  cleanup from design review)
01c,08jul02,spm  fixed modification history after automatic merge
01b,29jun02,wrs  automatic merge from version 4 of Accordion Munich branch:
                 added tunnel6in4_ctlinput routine
01a,24jun02,spm  automatic merge from version 1 of Accordion Munich branch:
                 (01a,xxxxxxx,kal  written)
*/

#ifndef __INCtunnelLibh
#define __INCtunnelLibh

#ifdef __cplusplus
extern "C" {
#endif

/* Must include avlLib.h */
#include <avlLib.h>

/*
 * The following two structures (TUN_PROTO, TUNNEL_CONFIG_PARAMS) are
 * passed to tunnelInstInit to configure tunnelLib. For virtual stack
 * environments it is possible to use different configuration
 * structures to achieve different tunneling configurations on a per
 * stack instance basis.
 */

typedef struct tunproto {
    short       pr_protocol;
    FUNCPTR     pr_input;
    FUNCPTR     pr_ctlinput;
    } TUN_PROTO;
    
typedef struct tunnelcfgparams {
    CFG_DATA_HDR    cfgh;
    int             mtuRefreshDelay;    /* Timeout (secs) for PMTU Refresh  */
    int             numXin4Protos;      /* Number of protos in Xin4ProtoArr */
    int             numXin6Protos;      /* Number of protos in Xin6ProtoArr */
    TUN_PROTO   *   Xin4ProtoArr;       /* Up to numXin4Protos size         */
    TUN_PROTO   *   Xin6ProtoArr;       /* Up to numXin6Protos size         */
    } TUNNEL_CONFIG_PARAMS;
    
/* 
 * Header length for prepended next hop IP
 * First byte contains TUNNEL_IPV4_GATE or TUNNEL_IPV6_GATE if the following
 * bytes contain a gateway address. Tunnel interfaces can use this to
 * determine if a gateway address is present.
 * Last 16 bytes contain an IPv4 or IPv6 address, starting at the first
 * byte of this block.
 */

#define TUNNEL_HDR_LEN      17

#define TUNNEL_IPV4_GATE    0x1
#define TUNNEL_IPV6_GATE    0x2

/*
 * Default MTU value for automatic tunnels, and for use by configured
 * tunnels until properly set up by tunnelAddrSet()/tunnelIfConfig().
 */
 
#define TUNNEL_DEFAULT_MTU  1280

/* Structure for linked list of tunnel interfaces */

typedef struct tunnelListElement
    {
    NODE        node;         /* lstLib element                               */
    char *      ifname;       /* Tunnel Interface name (e.g. "gif0")          */
    int         af;           /* Address family (e.g. AF_INET = Xin4)         */
    int         proto;        /* Protocol field (e.g. IPPROTO_IPv4 = 4inX     */
    int         overhead;     /* Number of bytes prepended by tunnel IF       */
    FUNCPTR     rcvFunc;      /* Function to call if a match is found         */
    void *      pDrvCtrl;     /* Tunnel's END_OBJ/DRV_CTRL structure          */
    BOOL        configTunnel; /* Is this a configured tunnel ?                */
    BOOL        performPmtud; /* Perform Tunnel Path MTU Discovery            */
    void *      ifMtuTimo;    /* GTF timer pointer for path MTU refresh       */
    void *      pLookup;      /* lookupListElement ptr to node in AVL tree    */    
    } TUNNEL_LIST_ELEMENT;


/* Structure for AVL tree nodes */

struct lookupListElement
    {
    AVL_NODE                lookupNode;     /* Used by avlLib                 */
    struct sockaddr *       srcAddr;        /* IPv4 or IPv6 source address    */
    struct sockaddr *       dstAddr;        /* IPv4 or IPv6 dest address      */
    void *                  tunnelIf;       /* TUNNEL_LIST_ELEMENT pointer    */
    };


/*
 * Macro for getting the source and destination addresses
 *
 * TUNNEL_ADDR_EXIST() checks if address are registered
 * TUNNEL_xxx_GET() return a pointer to the src/dst sockaddr structures
 */

#define TUNNEL_ADDR_EXIST(tunnelListPtr) \
            ((TUNNEL_LIST_ELEMENT *)(tunnelListPtr))->pLookup

#define TUNNEL_SRC_GET(tunnelListPtr) \
            ((struct lookupListElement *)(((TUNNEL_LIST_ELEMENT *)(tunnelListPtr))->pLookup))->srcAddr

#define TUNNEL_DST_GET(tunnelListPtr) \
            ((struct lookupListElement *)(((TUNNEL_LIST_ELEMENT *)(tunnelListPtr))->pLookup))->dstAddr

#define TUNNEL_PMTUD_IS_ON(tunnelListPtr) \
            ((TUNNEL_LIST_ELEMENT *)(tunnelListPtr))->performPmtud

/* Error values from configuration API */

#define     TUNNELLIB_IF_NOT_REGISTERED     0x01
#define     TUNNELLIB_IF_NOT_ATTACHED       0x02
#define     TUNNELLIB_WRONG_AF              0x03
#define     TUNNELLIB_ADDR_CONFLICT         0x04
#define     TUNNELLIB_INVALID_OPTIONS       0x05
#define     TUNNELLIB_INTERNAL_ERROR        0x06
#define     TUNNELLIB_MATCH_NOT_FOUND       0x07


/* tunnelTosSelect() parameters */

#define     TUNNEL_DIR_INGRESS              0x01
#define     TUNNEL_DIR_EGRESS               0x02

/* ECN/Diffser defines */

#define     TOS_ECN_FULL		0x01			/* Full ECN functionality */
#define     TOS_DIFF_ON			0x02			/* Diffserv functionality */


/* Function Declarations */

struct sockaddr; /* forward declaration */

void    tunnelIfShow (char *);
void    tunnelIfLookup (int, char *, char *);
STATUS  tunnelAddrSet (char *, struct sockaddr *, struct sockaddr *);
STATUS  tunnelAddrGet (char *, struct sockaddr *, struct sockaddr *);
STATUS  tunnelAddrToIfFind (struct sockaddr *, struct sockaddr *, char *);
void    tunnelIfConfig (char *, int, char *, char *);
STATUS  tunnelPmtudSet (char *, int);
STATUS  tunnelLibInit (void);
STATUS  tunnelInstInit (void *);
#ifdef VIRTUAL_STACK
STATUS  tunnelInstDestroy (VSNUM vsnum);
#endif /* VIRTUAL_STACK */
STATUS  tunnelDetach (void *);
void *  tunnelAttach (int, int, int, FUNCPTR, void *);
void    tunnelTosSelect (int, int, UINT8 *, UINT8 *);
void    tunnelIPv4Input (M_BLK_ID, int, int);
int     tunnelIPv6Input (M_BLK_ID *, int *, int);
void    tunnelIPv4inIPv4_ctlinput (int, struct sockaddr *, void *);
void    tunnelIPv6inIPv4_ctlinput (int, struct sockaddr *, void *);
void    tunnelIPv4inIPv6_ctlinput (int, struct sockaddr *, void *);
void    tunnelIPv6inIPv6_ctlinput (int, struct sockaddr *, void *);
int     tunnelIpOutput (int, M_BLK_ID, void *, void *, int, void *, BOOL, int, BOOL);
int     tunnelIfOutput (register struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *);

#ifdef MIP6
struct mip6_bc_internal;
struct mip6_bul_internal;
void *  mipTunnelAttach (int, int, int, FUNCPTR, struct mip6_bc_internal *,
                         struct mip6_bul_internal *);
STATUS mipTunnelDetach (TUNNEL_LIST_ELEMENT *);
#endif /* MIP6 */

#ifdef __cplusplus
}
#endif
                            
#endif /* __INCtunnelLibh */
